<?php

namespace co2_OS;

use \co2\dev\v0_0_0 as api;

function install_app($app,$version=null,$channel='stable')

{
	$app=strtolower($app);
	
	log::register("INSTALL_APP: Received install signal for app \"$app\" in channel $channel");
	
  $base=sysvar::get('apps')."/$app";
  
  if(!is_dir($base))
  
  {
    new api\bash\mkdir($base);
    log::register("INSTALL_APP: Created app folder");
  }
  
  $base="$base/$channel";
  
  if(!is_dir($base))
  
  {
    new api\bash\mkdir($base);
    log::register("INSTALL_APP: Created channel $channel folder in app folder");
  }

  if(is_null($version))
  
  {
    log::register('INSTALL_APP: No version specified. Querying co2 server to find app version in channel '.$channel.' for kernel version '.sysvar::get('version'));
    
    new api\SVN\export("http://co2.googlecode.com/svn/query/apps-manifest/$app.xml",sysvar::get('tmp').'/recommend-'.$app.'.xml');
    
    log::register("INSTALL_APP: co2 query server replied successfully :)");
    
    $x=new \DOMDocument;
    
    $x->load(sysvar::get('tmp').'/recommend-'.$app.'.xml');
    
    foreach($x->getElementsByTagName('kernel') as $k)
    if($k->getAttribute('version')==sysvar::get('version') && $k->getAttribute('channel')==$channel)
    $version=$k->getAttribute('recommend');
    
    unset($x);
    
    unlink(sysvar::get('tmp').'/recommend-'.$app.'.xml');
    
    if(is_null($version))
    
    {
      log::register('INSTALL_APP: No version were found. Exiting installation');
      
      throw new api\Exception('Missing version');
    }
    else
    log::register('INSTALL_APP: Version found: '.$version);
  }
  
  else
  log::register('INSTALL_APP: App version: '.$version);
  
  if($channel=='stable')
  $distrib='trunk';
  
  if($channel=='dev')
  $distrib='branches';
  
  if(is_dir("$base/$version"))
  
  {
    log::register("INSTALL_APP: App '$app/$version#$channel' already installed");
    
    throw new api\Exception('App already installed',null,ES_APP_ALREADY_INSTALLED);
  }

  log::register('INSTALL_APP: Downloading app now');
	
	new api\SVN\export("http://co2.googlecode.com/svn/$distrib/apps/$app/$version",$base."/$version");
	
	log::register('INSTALL_APP: App successfully downloaded :)');
	
	// app manifest

  log::register('INSTALL_APP: Parsing app manifest');
  
	$manifest=parse_manifest('app',$app,$version,$channel);
	
	$dependencies=array();

	foreach($manifest->dependencies as $dependency)
	
	switch($dependency->type)
	
	{
		case'app':
		
		  log::register("INSTALL_APP: Found dependency: app $dependency->name version $dependency->version in channel $dependency->channel");
		
			install_app($dependency->name,$dependency->version,$dependency->channel);
			
			$dependencies[]=array(aptitude::TYPE_APP,$dependency->name,$dependency->version,$dependency->channel);
		
		break;
		
		case'lib':
		
		  log::register("INSTALL_APP: Found dependency: lib $dependency->name version $dependency->version");
		
			install_lib($dependency->name,$dependency->version);
			
      $dependencies[]=array(aptitude::TYPE_LIB,$dependency->name,$dependency->version);
		
		break;
		
		case'api':
		
		  log::register("INSTALL_APP: Found dependency: api version $dependency->version in channel $dependency->channel");
		
			try
			{
			  install_api($dependency->version,$dependency->channel);
			}
			catch(api\Exception $e)
			{
			  if($e->getLevel()!=ES_API_VERSION_ALREADY_INSTALLED)
			  new api\Exception\rethrow($e);
			}
		
		break;
		
		case'pkg':
		
		  log::register("INSTALL_APP: Found dependency: pkg $dependency->name");
		  
		  new api\bash\aptitude\install($depency->name);
		
		break;
	}
  	  
	aptitude::add(aptitude::TYPE_APP,$app,$version,$channel);
	
	// dependencies
	
	foreach($dependencies as $d)
	dependency::add
			(
				$d,
				array(aptitude::TYPE_APP,$app,$version,$channel)
			);
}
